package fun.tan90.base.util;


import fun.tan90.trace.model.WindVectorData;
import fun.tan90.trace.model.WindWindowData;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 风速仪窗口计算
 */
public class WindowCalUtil {

    /**
     * 数据预处理
     */
    public static WindVectorData preCompute(String trainingBoatCode,
                                            Date arrivalDate,
                                            Integer windDirection,
                                            Long windSpeed) {
        if (Objects.isNull(windDirection) || Objects.isNull(windSpeed)) {
            return WindVectorData.builder()
                    .trainingBoatCode(trainingBoatCode)
                    .arrivalDate(arrivalDate)
                    .build();
        }
        // 根据角度得到弧度
        double windDirectionRad = Math.toRadians(windDirection);

        double speedX = Math.sin(windDirectionRad) * windSpeed;
        double speedY = Math.cos(windDirectionRad) * windSpeed;
        return WindVectorData.builder()
                .trainingBoatCode(trainingBoatCode)
                .direction(windDirection)
                .speed(windSpeed)
                .speedX(speedX)
                .speedY(speedY)
                .arrivalDate(arrivalDate)
                .build();
    }

    /**
     * 风速仪窗口计算
     */
    public static WindWindowData computeWindowData(List<WindVectorData> windVectorDataList) {
        int windowSize = windVectorDataList.size();

        WindVectorData windVectorData = windVectorDataList.get(windVectorDataList.size() - 1);
        String trainingBoatCode = windVectorData.getTrainingBoatCode();
        Date arrivalDate = windVectorData.getArrivalDate();

        windVectorDataList = windVectorDataList.stream().filter(n -> !Objects.isNull(n.getDirection()) && !Objects.isNull(n.getSpeed())).collect(Collectors.toList());
        if (windVectorDataList.isEmpty()) {
            return WindWindowData.builder()
                    .trainingBoatCode(trainingBoatCode)
                    .valid(false)
                    .arrivalDate(arrivalDate)
                    .build();
        }

        double direction = 0L;
        double speedX = windVectorDataList.stream().mapToDouble(WindVectorData::getSpeedX).average().orElse(0);
        double speedY = windVectorDataList.stream().mapToDouble(WindVectorData::getSpeedY).average().orElse(0);

        // 计算风速
        double speed = Math.sqrt(speedX * speedX + speedY * speedY);
        // 计算风向
        // 反正切函数
        double angle = Math.toDegrees(Math.abs(Math.atan2(speedY, speedX)));

        if (speedX > 0 && speedY > 0) {
            direction = 90 - angle;
        } else if (speedX > 0 && speedY < 0) {
            direction = angle + 90;
        } else if (speedX < 0 && speedY < 0) {
            direction = 90 + angle;
        } else if (speedX < 0 && speedY > 0) {
            direction = 360 + 90 - angle;
        }
        return WindWindowData.builder()
                .trainingBoatCode(trainingBoatCode)
                .valid(true)
                .windowSize(windowSize)
                .direction(direction)
                .speed(speed)
                .speedX(speedX)
                .speedY(speedY)
                .arrivalDate(arrivalDate)
                .build();
    }
}
